package cn.rwklyd.BookKeeping.service.impl;

import cn.rwklyd.BookKeeping.constant.MessageConstant;
import cn.rwklyd.BookKeeping.mapper.mybatisPlus.CategoryMapper;
import cn.rwklyd.BookKeeping.mapper.mybatisPlus.PlatformMapper;
import cn.rwklyd.BookKeeping.mapper.mybatisPlus.TransactionMapper;
import cn.rwklyd.BookKeeping.pojo.Category;
import cn.rwklyd.BookKeeping.pojo.Platform;
import cn.rwklyd.BookKeeping.pojo.Result;
import cn.rwklyd.BookKeeping.pojo.Transaction;
import cn.rwklyd.BookKeeping.pojo.vo.TransactionPageVO;
import cn.rwklyd.BookKeeping.pojo.vo.TransactionStatsVO;
import cn.rwklyd.BookKeeping.pojo.vo.TransactionVO;
import cn.rwklyd.BookKeeping.service.TransactionService;
import cn.rwklyd.BookKeeping.util.UserUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class TransactionServiceImpl extends ServiceImpl<TransactionMapper, Transaction> implements TransactionService {

    @Autowired
    private CategoryMapper categoryMapper;
    
    @Autowired
    private PlatformMapper platformMapper;

    @Override
    @Transactional
    public Result<Long> addTransaction(Transaction transaction) {
        // 设置当前登录用户ID
        Long userId = UserUtils.getCurrentUserId();
        if (userId == null) {
            return Result.error(MessageConstant.USER_NOT_LOGIN);
        }

        // 参数验证
        if (transaction.getCategoryId() == null) {
            return Result.error(MessageConstant.TRANSACTION_CATEGORY_EMPTY);
        }
        
        if (transaction.getPlatformId() == null) {
            return Result.error(MessageConstant.TRANSACTION_PLATFORM_EMPTY);
        }
        
        if (transaction.getAmount() == null) {
            return Result.error(MessageConstant.TRANSACTION_AMOUNT_EMPTY);
        }
        
        if (transaction.getAmount().doubleValue() <= 0) {
            return Result.error(MessageConstant.TRANSACTION_AMOUNT_INVALID);
        }
        
        // 获取分类信息，判断是收入还是支出
        Category category = categoryMapper.selectById(transaction.getCategoryId());
        if (category == null) {
            return Result.error("分类不存在");
        }
        
        // 设置用户ID
        transaction.setUserId(userId);
        
        // 设置默认值
        transaction.setCreateTime(LocalDateTime.now());
        transaction.setUpdateTime(LocalDateTime.now());
        transaction.setIsDeleted(0); // 默认未删除
        
        // 如果未设置交易时间，则使用当前时间
        if (transaction.getTransactionDate() == null) {
            transaction.setTransactionDate(LocalDateTime.now());
        }
        
        // 保存记录
        boolean success = this.save(transaction);
        if (success) {
            // 修改：返回新创建记录的ID
            return Result.success(transaction.getId());
        } else {
            return Result.error(MessageConstant.TRANSACTION_ADD_FAILED);
        }
    }

    @Override
    @Transactional
    public Result<String> deleteTransaction(Long id) {
        // 获取当前用户ID
        Long userId = UserUtils.getCurrentUserId();
        if (userId == null) {
            return Result.error(MessageConstant.USER_NOT_LOGIN);
        }
        
        // 查询记录是否存在且属于当前用户
        Transaction transaction = this.getById(id);
        if (transaction == null) {
            return Result.error(MessageConstant.TRANSACTION_NOT_FOUND);
        }
        
        if (!transaction.getUserId().equals(userId)) {
            return Result.error(MessageConstant.TRANSACTION_NO_PERMISSION);
        }
        
        // 逻辑删除（将is_deleted设为1）
        transaction.setIsDeleted(1);
        transaction.setUpdateTime(LocalDateTime.now());
        
        boolean success = this.updateById(transaction);
        if (success) {
            return Result.success(MessageConstant.TRANSACTION_DELETE_SUCCESS);
        } else {
            return Result.error(MessageConstant.TRANSACTION_DELETE_FAILED);
        }
    }

    @Override
    @Transactional
    public Result<String> updateTransaction(Transaction transaction) {
        // 获取当前用户ID
        Long userId = UserUtils.getCurrentUserId();
        if (userId == null) {
            return Result.error(MessageConstant.USER_NOT_LOGIN);
        }
        
        // 检查ID是否为空
        if (transaction.getId() == null) {
            return Result.error(MessageConstant.TRANSACTION_ID_EMPTY);
        }
        
        // 查询记录是否存在
        Transaction existingTransaction = this.getById(transaction.getId());
        if (existingTransaction == null || existingTransaction.getIsDeleted() == 1) {
            return Result.error(MessageConstant.TRANSACTION_NOT_FOUND);
        }
        
        // 检查是否有权限修改
        if (!existingTransaction.getUserId().equals(userId)) {
            return Result.error(MessageConstant.TRANSACTION_NO_PERMISSION);
        }
        
        // 参数验证
        if (transaction.getCategoryId() == null) {
            return Result.error(MessageConstant.TRANSACTION_CATEGORY_EMPTY);
        }
        
        if (transaction.getPlatformId() == null) {
            return Result.error(MessageConstant.TRANSACTION_PLATFORM_EMPTY);
        }
        
        if (transaction.getAmount() == null) {
            return Result.error(MessageConstant.TRANSACTION_AMOUNT_EMPTY);
        }
        
        if (transaction.getAmount().doubleValue() <= 0) {
            return Result.error(MessageConstant.TRANSACTION_AMOUNT_INVALID);
        }
        
        // 获取分类信息，判断是收入还是支出
        Category category = categoryMapper.selectById(transaction.getCategoryId());
        if (category == null) {
            return Result.error("分类不存在");
        }
        
        // 设置更新时间
        transaction.setUpdateTime(LocalDateTime.now());
        // 保持用户ID不变
        transaction.setUserId(existingTransaction.getUserId());
        // 保持创建时间不变
        transaction.setCreateTime(existingTransaction.getCreateTime());
        // 保持删除状态不变
        transaction.setIsDeleted(existingTransaction.getIsDeleted());
        
        boolean success = this.updateById(transaction);
        if (success) {
            return Result.success(MessageConstant.TRANSACTION_UPDATE_SUCCESS);
        } else {
            return Result.error(MessageConstant.TRANSACTION_UPDATE_FAILED);
        }
    }

    @Override
    @Transactional
    public Result<String> updateReceiptImage(Long id, String receiptImage) {
        // 获取当前用户ID
        Long userId = UserUtils.getCurrentUserId();
        if (userId == null) {
            return Result.error(MessageConstant.USER_NOT_LOGIN);
        }
        
        // 查询记录是否存在
        Transaction existingTransaction = this.getById(id);
        if (existingTransaction == null || existingTransaction.getIsDeleted() == 1) {
            return Result.error(MessageConstant.TRANSACTION_NOT_FOUND);
        }
        
        // 检查是否有权限修改
        if (!existingTransaction.getUserId().equals(userId)) {
            return Result.error(MessageConstant.TRANSACTION_NO_PERMISSION);
        }
        
        // 创建更新对象，只更新凭证图片字段
        Transaction updateTransaction = new Transaction();
        updateTransaction.setId(id);
        updateTransaction.setReceiptImage(receiptImage);
        updateTransaction.setUpdateTime(LocalDateTime.now());
        
        // 更新记录
        boolean success = this.updateById(updateTransaction);
        if (success) {
            return Result.success(MessageConstant.TRANSACTION_UPDATE_SUCCESS);
        } else {
            return Result.error(MessageConstant.TRANSACTION_UPDATE_FAILED);
        }
    }

    @Override
    public Result<Transaction> getTransactionById(Long id) {
        // 获取当前用户ID
        Long userId = UserUtils.getCurrentUserId();
        if (userId == null) {
            return Result.error(MessageConstant.USER_NOT_LOGIN);
        }
        
        // 查询消费记录
        Transaction transaction = this.getById(id);
        if (transaction == null || transaction.getIsDeleted() == 1) {
            return Result.error(MessageConstant.TRANSACTION_NOT_FOUND);
        }
        
        // 检查是否有权限查看
        if (!transaction.getUserId().equals(userId)) {
            return Result.error(MessageConstant.TRANSACTION_NO_PERMISSION);
        }
        
        return Result.success(transaction);
    }

    @Override
    public Result<IPage<Transaction>> getTransactionList(Integer page, Integer pageSize) {
        return queryTransactions(null, null, null, null, null, null, null, page, pageSize);
    }

    @Override
    public Result<IPage<Transaction>> queryTransactions(Long id, Long userId, Long categoryId, 
                                                      Long platformId, LocalDateTime startDate, 
                                                      LocalDateTime endDate, String remark, 
                                                      Integer page, Integer pageSize) {
        // 获取当前用户ID
        Long currentUserId = UserUtils.getCurrentUserId();
        if (currentUserId == null) {
            return Result.error(MessageConstant.USER_NOT_LOGIN);
        }
        
        // 构建查询条件
        LambdaQueryWrapper<Transaction> queryWrapper = new LambdaQueryWrapper<>();
        
        // 基础条件：未删除的
        queryWrapper.eq(Transaction::getIsDeleted, 0);
        
        // 用户ID条件处理
        if (userId != null) {
            // 如果指定了用户ID，则查询该用户的消费记录（需要权限检查，普通用户只能查自己的）
            if (!currentUserId.equals(userId)) {
                // TODO: 这里应该添加管理员权限检查，普通用户不能查看其他用户的消费记录
                // 暂时简单处理，非本人的查询请求返回错误
                return Result.error("无权查询其他用户的消费记录");
            }
            queryWrapper.eq(Transaction::getUserId, userId);
        } else {
            // 未指定用户ID，则查询当前用户的消费记录
            queryWrapper.eq(Transaction::getUserId, currentUserId);
        }
        
        // 根据ID查询
        if (id != null) {
            queryWrapper.eq(Transaction::getId, id);
        }
        
        // 根据分类ID查询
        if (categoryId != null) {
            queryWrapper.eq(Transaction::getCategoryId, categoryId);
        }
        
        // 根据平台ID查询
        if (platformId != null) {
            queryWrapper.eq(Transaction::getPlatformId, platformId);
        }
        
        // 根据消费日期范围查询
        if (startDate != null) {
            queryWrapper.ge(Transaction::getTransactionDate, startDate);
        }
        
        if (endDate != null) {
            queryWrapper.le(Transaction::getTransactionDate, endDate);
        }
        
        // 根据备注关键词模糊查询
        if (StringUtils.hasText(remark)) {
            queryWrapper.like(Transaction::getRemark, remark);
        }
        
        // 排序：按交易时间降序（最新的在前面）
        queryWrapper.orderByDesc(Transaction::getTransactionDate);
        
        // 设置默认值
        if (page == null) page = 1;
        if (pageSize == null) pageSize = 10;
        
        // 分页查询
        Page<Transaction> pageParam = new Page<>(page, pageSize);
        IPage<Transaction> transactionPage = this.page(pageParam, queryWrapper);
        
        return Result.success(transactionPage);
    }
    
    // 实现新增的方法
    @Override
    public Result<TransactionVO> getTransactionVOById(Long id) {
        // 获取当前用户ID
        Long userId = UserUtils.getCurrentUserId();
        if (userId == null) {
            return Result.error(MessageConstant.USER_NOT_LOGIN);
        }
        
        // 查询消费记录
        Transaction transaction = this.getById(id);
        if (transaction == null || transaction.getIsDeleted() == 1) {
            return Result.error(MessageConstant.TRANSACTION_NOT_FOUND);
        }
        
        // 检查是否有权限查看
        if (!transaction.getUserId().equals(userId)) {
            return Result.error(MessageConstant.TRANSACTION_NO_PERMISSION);
        }
        
        // 查询关联的分类和平台信息
        Category category = categoryMapper.selectById(transaction.getCategoryId());
        Platform platform = platformMapper.selectById(transaction.getPlatformId());
        
        // 构建VO对象
        TransactionVO vo = new TransactionVO();
        BeanUtils.copyProperties(transaction, vo);
        vo.setCategory(category);
        vo.setPlatform(platform);
        
        return Result.success(vo);
    }
    
    @Override
    public Result<TransactionPageVO> queryTransactionVOs(Long id, Long userId, Long categoryId, 
                                                Long platformId, LocalDateTime startDate, 
                                                LocalDateTime endDate, String remark, 
                                                Integer page, Integer pageSize) {
        try {
            log.info("开始查询交易记录: id={}, userId={}, categoryId={}, platformId={}, startDate={}, endDate={}, remark={}, page={}, pageSize={}",
                    id, userId, categoryId, platformId, startDate, endDate, remark, page, pageSize);
            
            // 先查询原始交易数据
            Result<IPage<Transaction>> result = queryTransactions(id, userId, categoryId, platformId, 
                                                              startDate, endDate, remark, page, pageSize);
            
            if (result == null) {
                log.error("查询交易记录返回结果为null");
                return Result.error("查询失败，系统内部错误");
            }
            
            if (result.getCode() == null || !result.getCode().equals(200)) {
                log.error("查询交易记录失败: {}", result.getMsg());
                return Result.error(result.getMsg() != null ? result.getMsg() : "查询失败，请检查参数");
            }
            
            IPage<Transaction> transactionPage = result.getData();
            if (transactionPage == null) {
                log.error("查询交易记录结果数据为null");
                return Result.error("查询结果为空");
            }
            
            List<Transaction> records = transactionPage.getRecords();
            log.info("查询到{}条交易记录", records != null ? records.size() : 0);
            
            // 转换为VO对象
            List<TransactionVO> voList = new ArrayList<>();
            if (records != null && !records.isEmpty()) {
                for (Transaction transaction : records) {
                    try {
                        // 查询关联的分类和平台信息
                        Category category = null;
                        Platform platform = null;
                        
                        if (transaction.getCategoryId() != null) {
                            category = categoryMapper.selectById(transaction.getCategoryId());
                            if (category == null) {
                                log.warn("交易记录{}的分类{}不存在", transaction.getId(), transaction.getCategoryId());
                            }
                        }
                        
                        if (transaction.getPlatformId() != null) {
                            platform = platformMapper.selectById(transaction.getPlatformId());
                            if (platform == null) {
                                log.warn("交易记录{}的平台{}不存在", transaction.getId(), transaction.getPlatformId());
                            }
                        }
                        
                        // 构建VO对象
                        TransactionVO vo = new TransactionVO();
                        BeanUtils.copyProperties(transaction, vo);
                        vo.setCategory(category);
                        vo.setPlatform(platform);
                        
                        voList.add(vo);
                    } catch (Exception e) {
                        log.error("处理交易记录{}时出错: {}", transaction.getId(), e.getMessage(), e);
                        // 继续处理下一条记录，不影响整体查询
                    }
                }
            }
            
            // 构建VO分页结果
            Page<TransactionVO> voPage = new Page<>(transactionPage.getCurrent(), transactionPage.getSize(), 
                                                 transactionPage.getTotal());
            voPage.setRecords(voList);
            
            // 获取当前用户ID
            Long currentUserId = UserUtils.getCurrentUserId();
            if (currentUserId == null) {
                return Result.error(MessageConstant.USER_NOT_LOGIN);
            }
            
            // 如果没有指定用户ID，则使用当前用户ID
            if (userId == null) {
                userId = currentUserId;
            }
            
            // 确定统计的时间范围
            LocalDateTime statisticsStartDate;
            LocalDateTime statisticsEndDate;
            
            if (startDate != null && endDate != null) {
                // 如果查询参数中提供了时间范围，则使用该范围进行统计
                statisticsStartDate = startDate;
                statisticsEndDate = endDate;
                log.info("使用查询参数的时间范围进行统计: {} 至 {}", statisticsStartDate, statisticsEndDate);
            } else {
                // 如果没有提供时间范围，则默认统计当前月份
                YearMonth currentMonth = YearMonth.now();
                statisticsStartDate = currentMonth.atDay(1).atStartOfDay();
                statisticsEndDate = currentMonth.atEndOfMonth().atTime(23, 59, 59);
                log.info("未提供时间范围，默认统计当前月份: {} 至 {}", statisticsStartDate, statisticsEndDate);
            }
            
            // 查询指定时间范围内的收入
            LambdaQueryWrapper<Transaction> incomeWrapper = new LambdaQueryWrapper<>();
            incomeWrapper.eq(Transaction::getUserId, userId)
                        .eq(Transaction::getIsDeleted, 0)
                        .ge(Transaction::getTransactionDate, statisticsStartDate)
                        .le(Transaction::getTransactionDate, statisticsEndDate)
                        .exists("SELECT 1 FROM category c WHERE c.id = transaction.category_id AND c.spend = 0");
            
            List<Transaction> incomeList = this.list(incomeWrapper);
            BigDecimal totalIncome = incomeList.stream()
                    .map(Transaction::getAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            
            // 查询指定时间范围内的支出
            LambdaQueryWrapper<Transaction> expenseWrapper = new LambdaQueryWrapper<>();
            expenseWrapper.eq(Transaction::getUserId, userId)
                         .eq(Transaction::getIsDeleted, 0)
                         .ge(Transaction::getTransactionDate, statisticsStartDate)
                         .le(Transaction::getTransactionDate, statisticsEndDate)
                         .exists("SELECT 1 FROM category c WHERE c.id = transaction.category_id AND c.spend = 1");
            
            List<Transaction> expenseList = this.list(expenseWrapper);
            BigDecimal totalExpense = expenseList.stream()
                    .map(Transaction::getAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            
            // 计算收支差额
            BigDecimal balance = totalIncome.subtract(totalExpense);
            
            // 创建返回对象
            TransactionPageVO pageVO = TransactionPageVO.fromIPage(voPage);
            pageVO.setTotalIncome(totalIncome);
            pageVO.setTotalExpense(totalExpense);
            pageVO.setTotalBalance(balance);
            
            log.info("查询交易记录成功，返回{}条记录，时间范围内总收入：{}，总支出：{}，收支差额：{}", 
                    voList.size(), totalIncome, totalExpense, balance);
            return Result.success(pageVO);
        } catch (Exception e) {
            log.error("查询交易记录异常: {}", e.getMessage(), e);
            return Result.error("查询失败：" + e.getMessage());
        }
    }

    @Override
    public Result<TransactionPageVO> getTransactionVOList(Integer page, Integer pageSize) {
        return queryTransactionVOs(null, null, null, null, null, null, null, page, pageSize);
    }

    @Override
    public Result<TransactionStatsVO> getUserTransactionStats() {
        // 获取当前用户ID
        Long userId = UserUtils.getCurrentUserId();
        if (userId == null) {
            return Result.error(MessageConstant.USER_NOT_LOGIN);
        }
        
        try {
            // 1. 查询用户的所有有效记账记录
            LambdaQueryWrapper<Transaction> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Transaction::getUserId, userId)
                       .eq(Transaction::getIsDeleted, 0)
                       .orderByAsc(Transaction::getTransactionDate); // 按交易日期升序排序
            
            List<Transaction> transactions = this.list(queryWrapper);
            
            // 2. 计算记账总数
            long totalCount = transactions.size();
            
            // 如果没有记录，直接返回全部为0的统计信息
            if (totalCount == 0) {
                return Result.success(new TransactionStatsVO(0L, 0L, 0L, 0L));
            }
            
            // 3. 计算记账天数（按交易日期去重）
            Set<LocalDate> distinctDays = transactions.stream()
                    .map(t -> t.getTransactionDate().toLocalDate())
                    .collect(Collectors.toSet());
            
            long totalDays = distinctDays.size();
            
            // 4. 计算连续记账天数
            // 将日期排序
            List<LocalDate> sortedDates = new ArrayList<>(distinctDays);
            Collections.sort(sortedDates);
            
            // 计算当前连续天数
            long currentConsecutiveDays = 1; // 至少有一天
            long maxConsecutiveDays = 1;
            
            // 从最近的日期开始，向前查找连续天数
            LocalDate today = LocalDate.now();
            LocalDate latestDate = sortedDates.get(sortedDates.size() - 1);
            
            // 如果最后一条记录不是今天的，则连续记账已经中断
            if (!latestDate.equals(today)) {
                currentConsecutiveDays = 0;
            } else {
                // 从今天开始，向前查找连续天数
                LocalDate prevDate = today;
                
                for (int i = sortedDates.size() - 1; i >= 0; i--) {
                    LocalDate currentDate = sortedDates.get(i);
                    
                    // 如果日期不连续，中断计算
                    if (ChronoUnit.DAYS.between(currentDate, prevDate) != 1) {
                        break;
                    }
                    
                    currentConsecutiveDays++;
                    prevDate = currentDate;
                }
            }
            
            // 5. 计算最长连续记账天数
            long currentStreak = 1;
            
            for (int i = 1; i < sortedDates.size(); i++) {
                // 如果当前日期与前一个日期相差1天，则连续
                if (ChronoUnit.DAYS.between(sortedDates.get(i-1), sortedDates.get(i)) == 1) {
                    currentStreak++;
                } else {
                    // 不连续，重置计数器
                    currentStreak = 1;
                }
                
                // 更新最长连续天数
                maxConsecutiveDays = Math.max(maxConsecutiveDays, currentStreak);
            }
            
            // 6. 创建并返回统计结果
            TransactionStatsVO statsVO = new TransactionStatsVO();
            statsVO.setTotalCount(totalCount);
            statsVO.setTotalDays(totalDays);
            statsVO.setConsecutiveDays(currentConsecutiveDays);
            statsVO.setMaxConsecutiveDays(maxConsecutiveDays);
            
            return Result.success(statsVO);
        } catch (Exception e) {
            log.error("获取用户记账统计信息异常: {}", e.getMessage(), e);
            return Result.error("获取统计信息失败：" + e.getMessage());
        }
    }
} 